package com.lu.model.entity;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.*;
import org.springframework.security.core.GrantedAuthority;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源表
 * </p>
 *
 * @author wangqieyu
 * @since 2022-07-26
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class SysResources extends Model<SysResources> implements Serializable, GrantedAuthority {

    private static final long serialVersionUID = 1L;

    /**
     * 权限id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 父ID
     */
    private Long pid;

    /**
     * 菜单名
     */
    private String name;

    /**
     * 显示顺序
     */
    private Integer sort;

    /**
     * 接口路由地址
     */
    private String url;

    /**
     * 1 目录菜单 2按钮
     * @see Type
     */
    private Integer type;

    /**
     * @see com.lu.model.enums.YesOrNoEnum
     */
    private Integer status;

    /**
     * 图标
     */
    private String icon;

    /**
     * 创建人
     */
    private Long createUserId;

    /**
     * 更新人
     */
    private Long updateUserId;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

    @Override
    protected Serializable pkVal() {
        return this.id;
    }

    @Override
    public String getAuthority() {
        return url;
    }

    @Getter
    @AllArgsConstructor
    public enum Type{
        MENU(1, "目录菜单"),
        BUTTON(2, "按钮"),
        ;
        private Integer type;
        private String description;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class TreeNodes {
        private Long id;
        private Long pid;
        /**
         * 菜单名
         */
        private String name;
        /**
         * 图标
         */
        private String icon;
        private Integer sort;
        /**
         * 接口路由地址
         */
        private String url;
        /**
         * 1 目录菜单 2按钮
         * @see Type
         */
        private Integer type;
        /**
         * @see com.lu.model.enums.YesOrNoEnum
         */
        private Integer status;
        /**
         * 图标
         */
        private List<TreeNodes> childs;
    }

    public static List<TreeNodes> treeNodes(List<SysResources> resourcesList, Long pid){
        List<TreeNodes> treeNodes = new ArrayList<>();
        if(ObjectUtil.isEmpty(resourcesList)){
            return treeNodes;
        }
        if(pid == null){
            pid = 0L;
        }
        //pid 下的孩子
        Map<Long, List<SysResources>> resourcesMap = resourcesList.stream().filter(o -> o.getPid() != 0).collect(Collectors.groupingBy(SysResources::getPid));
        Long finalPid = pid;
        List<SysResources> resources = resourcesList.stream().filter(o -> {
            if(finalPid == 0L){
                return o.getPid() == 0L;
            }else {
                return o.getId().longValue() == finalPid;
            }
        }).collect(Collectors.toList());
        for (SysResources resource : resources) {  //迭代父节点
            //父节点找孩子
            List<TreeNodes> childs = treeChildNodes(null, resourcesMap, resource.getId());
            if(ObjectUtil.isNotEmpty(childs)){
                childs = childs.stream().sorted(Comparator.comparing(o -> o.getSort())).collect(Collectors.toList());
            }
            treeNodes.add(TreeNodes.builder().id(resource.getId()).pid(resource.getPid())
                .name(resource.getName()).icon(resource.getIcon()).type(resource.getType()).status(resource.getStatus())
                .url(resource.getUrl()).sort(resource.getSort()).childs(childs).build());
        }
        return treeNodes.stream().sorted(Comparator.comparing(o -> o.getSort())).collect(Collectors.toList());
    }

    public static List<TreeNodes> treeChildNodes(List<TreeNodes> treeNodes, Map<Long, List<SysResources>> resourcesMap, Long pid){
        List<SysResources> resources = resourcesMap.get(pid);
        if(ObjectUtil.isEmpty(resources)){
            return treeNodes;
        }
        if(treeNodes == null){
            treeNodes = new ArrayList<>();
        }
        for (SysResources resource : resources) {
            //父节点找孩子
            List<TreeNodes> childs = treeChildNodes(null, resourcesMap, resource.getId());
            if(ObjectUtil.isNotEmpty(childs)){
                childs = childs.stream().sorted(Comparator.comparing(o -> o.getSort())).collect(Collectors.toList());
            }
            treeNodes.add(TreeNodes.builder().id(resource.getId()).pid(resource.getPid())
                .name(resource.getName()).icon(resource.getIcon()).type(resource.getType()).status(resource.getStatus())
                .url(resource.getUrl()).sort(resource.getSort()).childs(childs).build());
        }
        return treeNodes;
    }

}
